import requests
import re
import random
from frame_work.excel import get_all_data
from frame_work.util import (
    get_sql_info,
    check_tid,
    change_user_account_status,
    bind_tb,
    assert_result_dict,
    get_str
)
from frame_work.logger import Logger
from frame_work.login import PcLogin, AppLogin
from frame_work import menu_list
from multiprocessing import cpu_count, Pool
from frame_work.setting import *
from frame_work.yaml_file import YAML

logger = Logger(__name__).get_logger()


class Apply(object):
    # 定义申请成功数量初始值
    init_sum = 0

    def __init__(self, tid):
        self.tid = tid
        self.yaml = YAML(os.path.join(base_Dir, 'data', 'data.yaml'))

    @staticmethod
    def get_user_data():
        """
        从数据库里查：
        1：模特秀达人身份
        2：账户保证金>0
        :param nums:
        :return:
        """
        statement = """select uname from sk_user_mod where state=1 and deposit_remain>0"""
        params = ()
        value = get_sql_info(statement, params, meta={
            "info": "查询模特达人身份和账户有保证金的用户"
        })
        user_datas = []
        for v in value:
            user_datas.append(v.get('uname'))
        return user_datas

    @staticmethod
    def sum(res):
        # 批量申请累计数量 res为异步回调结果
        if res:
            Apply.init_sum += 1
        return Apply.init_sum

    @staticmethod
    def multi_async_apply(f, *args, **kwargs):
        """
        多进程异步执行批量申请
        :param f: 目标待执行函数
        :param args:
        :param kwargs:
        :return:
        """
        p = Pool(cpu_count())
        for uname in args:
            # 多进程异步执行APP申请申请
            res = p.apply_async(func=f, args=(uname,), callback=Apply.sum)
        # 不在接收任何进程
        p.close()
        # 等待所有子进程结束
        p.join()
        if kwargs.get('num') == Apply.init_sum:
            logger.info("达到申请成功的数量:%s" % Apply.init_sum)
        else:
            logger.info(
                "还差: %s个未申请成功,可能是没有保证金/非模特大人等,请换个账户！" %
                (kwargs.get('num') - Apply.init_sum))


class AppApply(Apply):

    # APP活动申请
    def __init__(self, tid):
        Apply.__init__(self, tid)

    @staticmethod
    def get_session(uname):
        # 返回登录session
        login = AppLogin(uname)
        sign = login.appget_sign()
        return sign

    def app_apply(self, uname):
        """
        app端申请模特秀
        :param uname:
        :return:
        """
        statement = """select * from sk_user u,sk_user_address ua where u.uid=ua.uid and u.uname = %s and ua.is_default=1"""
        params = (uname,)
        value = get_sql_info(statement, params, meta={
            "info": "查询address_id和uid"
        })
        sign = AppApply.get_session(uname)
        if sign:
            yaml_data = self.yaml.get_data('join_modshow')
            yaml_data.get('data').update({'uid': value[0].get("uid"),
                                          'tid': self.tid,
                                          'sign': sign,
                                          'address_id': value[0].get("id")
                                          })
            logger.debug('开始app申请模特秀活动')
            response = requests.post(
                url=yaml_data.get('url'),
                data=yaml_data.get('data'),
                headers=yaml_data.get('header')).text
            status = assert_result_dict(
                response, uname + '申请tid:' + str(self.tid) + '模特秀活动')
            if status:
                Apply.init_sum += 1
            return status
        else:
            logger.debug('APP登录失败')


def main():
    while True:
        # 选择功能菜单
        menu_list.modshow_apply_menu()
        # 选择
        choise = input("请输入您的选择: ")
        if choise in ('q', 'Q'):
            break
        try:
            tid = int(input(u'请输入活动tid: '))
            status = check_tid(tid)
            if not status:
                raise Exception("活动tid不存在try表，请核实后在重新输入")
        except Exception as e:
            logger.error("reszon => %s" % e)
        else:
            if choise == '1':
                # app端申请，需要在app端做登录以获取申请接口参数sign值
                uname = input('请输入您指定的试客账户名: ')
                app_apply_obj = AppApply(tid)
                app_apply_obj.app_apply(uname)
            elif choise == '2':
                # 批量app申请
                num = int(input(u'请输入批量申请数量: '))
                app_apply_obj = AppApply(tid)
                user_datas = app_apply_obj.get_user_data()
                if len(user_datas) < num:
                    logger.info("查询数据库中只有%s个用户符合条件(模特达人身份/有保证金)申请,不够你输入的数量,你自己造数据吧,先申请这些" % len(user_datas))
                else:
                    user_datas = user_datas[0:num]
                app_apply_obj.multi_async_apply(
                    app_apply_obj.app_apply, *user_datas, num=num)
            else:
                logger.info("没有对应的选项,请按选项输入...")
                break


if __name__ == '__main__':
    main()
